package org.softmed.ATComm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;

public class DefaultSMSToATTranslator implements SMSToATTranslator {

	InputStream inputStream;
	OutputStream outputStream;
	BufferedReader bufferedReader;
	PrintStream printStream;

	public void sendSMS(String number, String msg, InputStream in,
			OutputStream out) throws IOException {

		inputStream = in;
		outputStream = out;

		bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

		printStream = new PrintStream(outputStream, true);

		// Write to the output
		exchangeMessage("AT"); // returns OK

		exchangeMessage("AT+CMGF=1"); // returns new line or line feed
		String line = bufferedReader.readLine(); // returns OK
		validateResponse(line, "ERROR CHANGING TO SMS CREATION MODE ");

		printStream.print("AT+CMGW=\"" + number + "\"");
		printStream.print("\r");
		printStream.flush();// send the number with the return feed, starting
		// the send
		// text part

		bufferedReader.readLine(); // read the return feed
		System.out.println("PREVIOUS COMMAND - " + bufferedReader.readLine()); // reads
		// the
		// AT+CMGW
		// that was
		// sent to
		// the
		// stream
		System.out.println("CR" + bufferedReader.read()); // carriage return
		System.out.println("LF" + bufferedReader.read()); // line feed
		System.out.println(">" + bufferedReader.read()); // >
		System.out.println("SPACE" + bufferedReader.read()); // space

		System.out.println("SMS Text : " + msg);

		printStream.print(msg); // sends the message;

		byte b = 0x1A;
		printStream.write(b); // sends the CTRL+Z byte to finish the message
		printStream.flush();

		waitForInputReady();
		System.out.println("Available : " + inputStream.available());
		String msgId = null;
		System.out.println("1 - MESSAGE SENT:" + getPortResponseWhenReady());

		System.out.println("RESPONSE:" + (msgId = getPortResponseWhenReady()));

		// if error throw exception
		validateResponse(msgId, "ERROR CREATING MESSAGE ");

		if (msgId != null && msgId.startsWith("\r\n+CMGW: ")) {
			msgId = msgId.substring(msgId.indexOf(' ') + 1);
			msgId = msgId.substring(0, msgId.indexOf("\r\n"));
			System.out.println("SMS IS : " + msgId);
		}

		shortExchangeMessage("AT+CMSS=" + msgId);
		// waitForMiliSeconds(5000);
		line = getPortResponseWhenReady();
		// if error throw exception
		validateResponse(line, "ERROR SENDING MESSAGE ");

		System.out.println("SENT RESPONSE: " + line);

		shortExchangeMessage("AT+CMGD=" + msgId);
		line = getPortResponseWhenReady();

		// if error throw exception
		validateResponse(msgId, "ERROR DELETING MESSAGE ");

		System.out.println("DELETE RESPONSE: " + line);

	}

	protected void validateResponse(String response, String error)
			throws IOException {
		if (response.contains("ERROR"))
			throw new IOException(error);
	}

	protected String getPortResponseWhenReady() throws IOException {
		int size = waitForInputReady();
		return readTextFromLine(size);
	}

	protected int waitForInputReady() throws IOException {
		int available = -1;

		while ((available = inputStream.available()) <= 0) {
			waitForMiliSeconds(50);
		}
		return available;
	}

	protected void waitAShortWhile() {
		waitForMiliSeconds(100);
	}

	protected void waitForMiliSeconds(long miliseconds) {
		try {
			Thread.sleep(miliseconds);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	protected String readTextFromLine() {
		String text = "";
		try {
			while (true)
				text += (char) bufferedReader.read();
		} catch (Throwable t) {
			t.printStackTrace();
		}

		System.out.println(text);
		return text;

	}

	protected String readTextFromLine(int size) throws IOException {
		String text = "";
		for (int i = 0; i < size; i++) {
			text += (char) bufferedReader.read();
		}
		// System.out.println(text);
		return text;

	}

	protected void sendIntValue(int value) throws IOException {
		// os.print("\r\n");
		printStream.print(value);
		printStream.print("\n");
		printStream.flush();
		// System.out.println(is.read());
	}

	protected String exchangeMessage(String msg) throws IOException {
		// System.out.println("SENT:");
		System.out.println(msg);
		printStream.print(msg);
		printStream.print("\r\n"); // Append a carriage return with a line feed
		printStream.flush();

		bufferedReader.readLine(); // First read will contain the echoed
		// command you sent
		// to it. In this case: "AT"
		bufferedReader.readLine(); // Second read will remove the extra line
		// feed that AT
		// generates as output
		String response = bufferedReader.readLine();
		// System.out.println("RECEIVED:");
		System.out.println(response);

		return response;
	}

	protected void shortExchangeMessage(String msg) throws IOException {
		// System.out.println("SENT:");
		System.out.println(msg);
		printStream.print(msg);
		printStream.print("\r\n"); // Append a carriage return with a line feed
		printStream.flush();

		System.out.println("ECHO:" + bufferedReader.readLine()); // First
		// read will
		// contain the echoed
		// command you sent
		// to it. In this case: "AT"

	}

	protected String exchangeMessageEnd(String msg) throws IOException {
		// System.out.println("SENT:");
		System.out.println(msg);
		printStream.print(msg);
		printStream.append((char) 26);
		// os.print(""+26); // Append CTRL+Z
		printStream.print("\r\n");
		printStream.print("\r\n");
		printStream.flush();

		System.out.println(bufferedReader.readLine()); // First read will
		// contain the
		// echoed command you sent
		// to it. In this case: "AT"
		System.out.println(bufferedReader.readLine()); // Second read will
		// remove the extra
		// line feed that AT
		// generates as output
		String response = bufferedReader.readLine();
		// System.out.println("RECEIVED:");
		System.out.println(response);

		return response;
	}

	protected void readData() {
		try {
			// StringBuffer sb = new StringBuffer();
			// String text = "";
			int count = -1;
			while ((count = inputStream.available()) > 0) {
				// System.out.println(count);
				for (int i = 0; i < count; i++) {
					int read = inputStream.read();
					// System.out.println("read int : " + read);

					char c = (char) read;
					System.out.print(c);
					// sb.append(""+c);
					// text += c;
				}
				// System.out.println("Final Read : " + text);
			}
			// inputStream.
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
